#include "example.hpp"
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

using namespace std;

// 如果编译器不支持C++11的std::make_unique，则手动实现
#if __cplusplus == 201103L
#include <memory>
namespace std {
	template<typename T, typename... Args>
	unique_ptr<T> make_unique(Args &&...args) {
		return unique_ptr<T>(new T(std::forward<Args>(args)...));
	}
} // namespace std
#endif

unique_ptr<JsonData> ParseJsonData(const string &filename) {
	ifstream ifs(filename);
	if (!ifs) return nullptr;

	string content((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));

	cJSON *root = cJSON_Parse(content.c_str());
	if (!root) return nullptr;

	auto data = make_unique<JsonData>();

	// 解析基本类型
	data->String  = cJSON_GetStringValue(cJSON_GetObjectItem(root, "string"));
	data->Number  = cJSON_GetObjectItem(root, "number")->valueint;
	data->Float   = cJSON_GetObjectItem(root, "float")->valuedouble;
	data->Boolean = cJSON_IsTrue(cJSON_GetObjectItem(root, "boolean"));

	// 解析数组
	cJSON *array = cJSON_GetObjectItem(root, "array");
	if (cJSON_IsArray(array)) {
		for (int i = 0; i < cJSON_GetArraySize(array); i++) {
			cJSON *item = cJSON_GetArrayItem(array, i);
			if (cJSON_IsString(item)) {
				data->Array.emplace_back(cJSON_GetStringValue(item));
			} else if (cJSON_IsNumber(item)) {
				data->Array.emplace_back(item->valueint);
			} else if (cJSON_IsBool(item)) {
				data->Array.emplace_back(cJSON_IsTrue(item));
			} else if (cJSON_IsObject(item)) {
				JsonData::ArrayElement::Object obj;
				obj.NestedObject = cJSON_GetStringValue(cJSON_GetObjectItem(item, "nestedObject"));
				data->Array.emplace_back(obj);
			} else if (cJSON_IsArray(item)) {
				JsonData::ArrayElement::Array arr;
				for (int j = 0; j < cJSON_GetArraySize(item); j++) {
					arr.Elements.push_back(cJSON_GetArrayItem(item, j)->valueint);
				}
				data->Array.emplace_back(arr);
			}
		}
	}

	// 其他字段解析类似，限于篇幅省略...

	cJSON_Delete(root);
	return data;
}

void PrintElement(const JsonData::ArrayElement &elem) {
	switch (elem.type) {
		case JsonData::ArrayElement::Type::String:
			cout << "String: " << elem.StringValue << endl;
			break;
		case JsonData::ArrayElement::Type::Int:
			cout << "Int: " << elem.IntValue << endl;
			break;
		case JsonData::ArrayElement::Type::Bool:
			cout << "Bool: " << (elem.BoolValue ? "true" : "false") << endl;
			break;
		case JsonData::ArrayElement::Type::Object:
			cout << "Object {" << endl;
			cout << "  NestedObject: " << elem.ObjectValue.NestedObject << endl;
			cout << "}" << endl;
			break;
		case JsonData::ArrayElement::Type::Array:
			cout << "Array [ ";
			for (const auto &num: elem.ArrayValue.Elements) {
				cout << num << " ";
			}
			cout << "]" << endl;
			break;
		default:
			cerr << "Unexpected element type!" << endl;
			break;
	}
}


int main() {
	printf("=== Example Cpp Demo\n");
	auto data = ParseJsonData("etc/example.json");
	if (!data) {
		cerr << "Failed to parse JSON" << endl;
		return 1;
	}

	// 打印数据
	cout << "String: " << data->String << endl;
	cout << "Number: " << data->Number << endl;
	// 其他字段打印...

	return 0;
}
